package com.sailfish.springbootdemo.utils;

import com.alibaba.fastjson.JSONObject;
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import javax.net.ssl.*;
import javax.servlet.http.Part;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.Charset;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class HttpUtil {

    /**
     * 向指定 URL 发送POST方法的请求
     *
     * @param url   发送请求的 URL
     * @param param 请求参数，请求参数应该是 name1=value1&name2=value2 的形式。
     * @return 所代表远程资源的响应结果
     */
    public static String sendPost(String url, String param) {
        PrintWriter out = null;
        BufferedReader in = null;
        String result = "";
        try {
            URL realUrl = new URL(url);
            // 打开和URL之间的连接
            URLConnection conn = realUrl.openConnection();
            // 设置通用的请求属性
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent",
                    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            // 发送POST请求必须设置如下两行
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.connect();
            // 获取URLConnection对象对应的输出流
            out = new PrintWriter(conn.getOutputStream());
            // 发送请求参数
            out.print(param);
            // flush输出流的缓冲
            out.flush();
            // 定义BufferedReader输入流来读取URL的响应
            InputStream instream = conn.getInputStream();
            if (instream != null) {
                in = new BufferedReader(new InputStreamReader(instream));
                String line;
                while ((line = in.readLine()) != null) {
                    result += line;
                }
            }


        } catch (Exception e) {
            e.printStackTrace();
        }
        //使用finally块来关闭输出流、输入流
        finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }

        return result;
    }

    /**
     * 发起http请求获取返回结果
     *
     * @param req_url 请求地址
     * @return
     */
    public static String sendGet(String req_url) {
        StringBuffer buffer = new StringBuffer();
        try {
            URL url = new URL(req_url);
            HttpURLConnection httpUrlConn = (HttpURLConnection) url.openConnection();

            httpUrlConn.setDoOutput(false);
            httpUrlConn.setDoInput(true);
            httpUrlConn.setUseCaches(false);

            httpUrlConn.setRequestMethod("GET");
            httpUrlConn.connect();

            // 将返回的输入流转换成字符串
            InputStream inputStream = httpUrlConn.getInputStream();
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

            String str = null;
            while ((str = bufferedReader.readLine()) != null) {
                buffer.append(str);
            }
            //res = new String(buffer.toString().getBytes("iso-8859-1"),"utf-8");
            bufferedReader.close();
            inputStreamReader.close();
            // 释放资源
            inputStream.close();
            inputStream = null;
            httpUrlConn.disconnect();

        } catch (Exception e) {
            e.printStackTrace();
        }
        return buffer.toString();
    }

    /**
     * get请求
     *
     * @param url
     * @return
     * @throws IOException
     */
    public static String sendGetRequest(String url) throws IOException {
        // 禁用 SSL 证书验证
        disableSSLVerification();
        URL requestUrl = new URL(url);
        // 打开连接
        HttpURLConnection connection = (HttpURLConnection) requestUrl.openConnection();
        // 设置请求方法
        connection.setRequestMethod("GET");
        connection.setRequestProperty("SubnetApiKey", "RW9TIkREvvLk95apG1V6qU&46oNkLZ2V");
        // 发起请求并获取响应状态码
        int responseCode = connection.getResponseCode();
        // 根据响应状态码处理结果
        if (responseCode == HttpURLConnection.HTTP_OK) {
            // 读取响应内容
            BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            StringBuilder response = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                response.append(line);
            }
            reader.close();
            // 关闭连接
            connection.disconnect();
            return response.toString();
        } else {
            // 关闭连接
            connection.disconnect();
            throw new IOException("请求失败，响应代码：" + responseCode);
        }
    }


    private static void disableSSLVerification() {
        try {
            // 获取 SSL 上下文对象
            SSLContext sslContext = SSLContext.getInstance("TLS");
            // 创建信任管理器对象，用于自定义信任策略
            TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
                public void checkClientTrusted(X509Certificate[] chain, String authType) {
                }

                public void checkServerTrusted(X509Certificate[] chain, String authType) {
                }

                public X509Certificate[] getAcceptedIssuers() {
                    return null;
                }
            }};

            // 初始化 SSL 上下文对象，并将信任管理器对象关联
            sslContext.init(null, trustAllCerts, new java.security.SecureRandom());

            // 获取 SSL 套接字工厂对象，并将 SSL 上下文对象关联
            HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());

            // 获取主机名验证对象，用于自定义主机名验证策略
            HostnameVerifier allHostsValid = new HostnameVerifier() {
                public boolean verify(String hostname, SSLSession session) {
                    return true;
                }
            };
            // 关联主机名验证对象
            HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 上传文件 HttpClient+MultipartRequestEntity
     * @param url
     * @param param
     * @param file
     * @return
     */
    /*public static String doPostFile1(String url, Map<String, String> param, File file) {
        // 创建Httpclient对象
//		CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpClient httpClient = new HttpClient();
        CloseableHttpResponse response = null;
        PostMethod post = new PostMethod(url);
        String resultString = "";
        List<Part> list = new ArrayList<>();
        httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(500000);
        try {
            list.add(new FilePart("file", file));
            if (param != null) {
                for (String key : param.keySet()) {
                    list.add(new StringPart(key, param.get(key), "UTF-8"));
                }
            }
            Part[] parts = list.toArray(new Part[list.size()]);
            MultipartRequestEntity entity = new MultipartRequestEntity(parts, new HttpMethodParams());
            post.setRequestEntity(entity);
            post.addRequestHeader("token", param.get("token"));
            System.out.println(entity.getContentType());
            int status  = httpClient.executeMethod(post);
            System.out.println(status);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            post.releaseConnection();
        }
        return "";
    }*/

    /**
     * 上传文件 HttpClient+MultipartEntity,这里需要httpmime包辅助
     *
     * @param url
     * @param param
     * @param file
     * @return
     */
    public static String doPostFile2(String url, Map<String, String> param, File file) {
        // 创建Httpclient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();
        // 处理https链接
//		if (url.startsWith("https://")) {
//			httpClient = sslClient();
//		}
        CloseableHttpResponse response = null;
        String resultString = null;
        try {
            HttpPost httppost = new HttpPost(url);
            FileBody filebody = new FileBody(file);
            MultipartEntity entity = new MultipartEntity(HttpMultipartMode.RFC6532, null, Charset.forName("UTF-8"));
            entity.addPart("file", filebody);
            // 添加其他字符串参数
            if (param != null) {
                for (String key : param.keySet()) {
                    entity.addPart(key, new StringBody(param.get(key), Consts.UTF_8));
                }
            }
            System.out.println(entity);
            httppost.addHeader("Content-Type", "multipart/form-data");
            httppost.setEntity(entity);
            //httppost.setConfig(getConfig());
            response = httpClient.execute(httppost);
            resultString = EntityUtils.toString(response.getEntity(), "utf-8");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return resultString;
    }

    public static String doPostFile3(String url, String token, String sourceAccount, Map<String, String> param, File file) {
        // 创建Httpclient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        String resultString = null;
        try {
            HttpPost httppost = new HttpPost(url);
            FileBody filebody = new FileBody(file);
            MultipartEntity entity = new MultipartEntity(HttpMultipartMode.RFC6532, null, Charset.forName("UTF-8"));
            entity.addPart("files", filebody);

            // 添加其他字符串参数
            if (param != null) {
                for (String key : param.keySet()) {
                    entity.addPart(key, new StringBody(param.get(key), Consts.UTF_8));
                }
            }

            System.out.println(entity);
            httppost.addHeader("Content-Type", "multipart/form-data");
            httppost.addHeader("Source-Account", sourceAccount);
            httppost.addHeader("token", token);
            httppost.setEntity(entity);
            //httppost.setConfig(getConfig());
            response = httpClient.execute(httppost);
            resultString = EntityUtils.toString(response.getEntity(), "utf-8");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return resultString;
    }

    /**
     * @param url     请求地址
     * @param builder
     * @return
     */
    public static String sendPostFormData(String url, MultipartEntityBuilder builder) throws Exception {
        String StringResult = "";
        //不需要手动关闭httpClient
        HttpClient httpClient = HttpClientBuilder.create().build();
        HttpPost httpPost = new HttpPost(url);

        // 构建form-data请求体
        HttpEntity entity = builder.build();
        httpPost.setEntity(entity);

        // 发送请求并获取响应
        HttpResponse response = null;
        response = httpClient.execute(httpPost);
        HttpEntity responseEntity = response.getEntity();
        StringResult = EntityUtils.toString(responseEntity);
        return StringResult;
    }

    public static String sendPostJson(String postUrl, JSONObject params) throws Exception {
        URL url = new URL(postUrl);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();

        conn.setRequestMethod("POST");
        conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
        conn.setConnectTimeout(500 * 1000);
        conn.setReadTimeout(500 * 1000);
        conn.setDoOutput(true);

        // 发送数据
        try (OutputStream outputStream = conn.getOutputStream()) {
            outputStream.write(params.toString().getBytes("UTF-8"));
            outputStream.flush();
        }

        // 获取返回值
        try (InputStream inputStream = conn.getInputStream();
             BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream))) {
            StringBuilder stringBuilder = new StringBuilder();
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                stringBuilder.append(line);
            }
            return stringBuilder.toString();
        }
    }

    public static String sendPostJsonToken(String postUrl, JSONObject params, String token) throws Exception {
        URL url = new URL(postUrl);
        //2. 创建HttpURLConnection对象
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        //3. 设置请求方法
        conn.setRequestMethod("POST");
        //4. 设置请求头
        conn.setRequestProperty("Content-Type", "application/json");
        conn.setRequestProperty("Charset", "UTF-8");
        conn.setRequestProperty("Authorization", token);
        //5. 设置参数
       /* JSONObject jsonpObject = new JSONObject();
        jsonpObject.put("key1", "value1");
        jsonpObject.put("key2", "value2");*/
        //6. 发送数据
        conn.setDoOutput(true);
        OutputStream outputStream = conn.getOutputStream();
        outputStream.write(params.toString().getBytes());
        outputStream.flush();
        outputStream.close();

        //7. 获取返回值
        InputStream inputStream = conn.getInputStream();
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
        StringBuilder stringBuilder = new StringBuilder();
        String line = null;
        while ((line = bufferedReader.readLine()) != null) {
            stringBuilder.append(line);
        }
        return stringBuilder.toString();
    }

    public static String sendPostJsonWithHeader(String postUrl, JSONObject params, String sysid, String syspwd, String userId) throws Exception {
        URL url = new URL(postUrl);
        //2. 创建HttpURLConnection对象
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        //3. 设置请求方法
        conn.setRequestMethod("POST");
        //4. 设置请求头
        conn.setRequestProperty("Content-Type", "application/json");
        conn.setRequestProperty("Charset", "UTF-8");
        conn.setRequestProperty("sysid", sysid);
        conn.setRequestProperty("syspwd", syspwd);
        conn.setRequestProperty("userId", userId);
        //6. 发送数据
        conn.setDoOutput(true);
        OutputStream outputStream = conn.getOutputStream();
        outputStream.write(params.toString().getBytes());
        outputStream.flush();
        outputStream.close();

        //7. 获取返回值
        InputStream inputStream = conn.getInputStream();
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
        StringBuilder stringBuilder = new StringBuilder();
        String line = null;
        while ((line = bufferedReader.readLine()) != null) {
            stringBuilder.append(line);
        }
        return stringBuilder.toString();
    }
}
